package com.vistor.sinkingviewtest;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

import java.util.logging.Handler;

public class WaveView extends View {

    private static final String MAIN_COLOR = "#1998FA";
    private static final int waveSpeech = 150;                                                      //当前波浪的速度
    private static final int waveHeight = 80;                                                       //sin曲线振幅的高度
    private static final int cycle = 160;                                                           //sin曲线的长度：一个周期的长度
    private static final int translateX = cycle / 4;                                                 //每次平移的长度，为四分之一个周期

    private int width;                                                                              //View的宽高
    private int height;

    private Paint wavePaint;                                                                        //View的画笔
    private Paint textPaint;
    private Paint circlePaint;

    private Path path;                                                                              //波浪的路径
    private Point startPoint;                                                                       //sin曲线的起点坐标
    private int progress = 0;                                                                       //当前波浪的进度

    private boolean isAutoIncrease = false;                                                         //是否启用了自动增长进度
    private boolean stopWave = false;                                                               //停止水波纹动画

    public WaveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public WaveView(Context context) {
        super(context);
        initPaint();
    }

    private void initPaint() {
        path = new Path();
                                                                                                    //波浪的画笔
        wavePaint = new Paint();
        wavePaint.setAntiAlias(true);
        wavePaint.setStyle(Paint.Style.FILL);
        wavePaint.setColor(Color.parseColor(MAIN_COLOR));
                                                                                                    //圆的画笔
        circlePaint = new Paint();
        circlePaint.setStrokeWidth(5);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.parseColor(MAIN_COLOR));
                                                                                                    //字体的画笔
        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(50);
        textPaint.setColor(Color.BLUE);

        startPoint = new Point(-cycle * 4, 0);                                                  //初始化起点，为屏幕外的一个周期
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        setPadding(20, 20, 20, 20);                                         //设置内间距
        clipCicle(canvas);                                                                          //裁剪画布为圆形
        drawCicleBorder(canvas);                                                                    //绘制圆形边框
        drawWavePath(canvas);                                                                       //绘制波浪区域
        drawProcessText(canvas);                                                                    //绘制进度文字

        if (isAutoIncrease) {                                                                       //自动增长进度
            if (progress >= 100) {
                progress = 0;
            } else {
                progress++;
            }
        }

        if (!stopWave){
            postInvalidateDelayed(waveSpeech);                                                      //更新UI
        }
    }

    public void stop(){
        new android.os.Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                stopWave = true;
            }
        },1000);
    }

    /**
     * 绘制进度文字
     * @param canvas 画布
     */
    private void drawProcessText(Canvas canvas) {
        Rect targetRect = new Rect(0, 0, width, height);                                   //画布的大小
        Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
        int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
                                                                                                    // 下面这行是实现水平居中，drawText对应改为传入targetRect.centerX()
        textPaint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(progress + "%", targetRect.centerX(), baseline, textPaint);
    }

    /**
     * 绘制波浪区域
     * @param canvas 画布
     */
    private void drawWavePath(Canvas canvas) {

        startPoint.y = (int) ((1 - (progress / 100.0)) * (height / 2 + width / 2));                 //根据进度改变起点坐标的y值
        path.moveTo(startPoint.x, startPoint.y);                                                    //移动区域起点
        int j = 1;

        for (int i = 1; i <= 8; i++) {                                                              //循环绘制正弦曲线区域，循环两个周期
            if (i % 2 == 0) {
                path.quadTo(startPoint.x + (cycle * j), startPoint.y + waveHeight,          //波峰
                        startPoint.x + (cycle * 2) * i, startPoint.y);
            } else {
                path.quadTo(startPoint.x + (cycle * j), startPoint.y - waveHeight,          //波谷
                        startPoint.x + (cycle * 2) * i, startPoint.y);
            }
            j += 2;
        }
                                                                                                    //绘制封闭的区域
        path.lineTo(width, height);                                                                 //右下角
        path.lineTo(startPoint.x, height);                                                          //左下角
        path.lineTo(startPoint.x, startPoint.y);                                                    //起点
        path.close();
                                                                                                    //绘制区域
        canvas.drawPath(path, wavePaint);
        path.reset();
                                                                                                    //一开始的起点是在-160，160 = 40 + 40 + 40 + 40，走完一个周期则回到原点
        if (startPoint.x + translateX >= 0) {
            startPoint.x = -cycle * 4;
        } else {
            startPoint.x += translateX;
        }
    }

    /**
     * 绘制圆形边框
     * @param canvas 画布
     */
    private void drawCicleBorder(Canvas canvas) {
        canvas.drawPaint(circlePaint);
        canvas.drawCircle(width / 2, height / 2, width / 2, circlePaint);
    }

    /**
     * 裁剪画布为圆形
     * @param canvas 画布
     */
    private void clipCicle(Canvas canvas) {
        Path circlePath = new Path();
        circlePath.addCircle(width / 2, height / 2, width / 2, Path.Direction.CW);
        canvas.clipPath(circlePath);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = measureSize(400, widthMeasureSpec);                                     //由于是一个圆形，所以取的值是宽高的最小值
        height = measureSize(400, heightMeasureSpec);
        width = Math.min(width, height);
        height = Math.min(width, height);
        setMeasuredDimension(width, height);
    }

    /**
     * 测量宽高
     * @param defaultSize 默认尺寸
     * @param measureSpec 测量模式
     * @return 测量的高度
     */
    private int measureSize(int defaultSize, int measureSpec) {
        int result = defaultSize;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
        switch (mode) {
            case MeasureSpec.UNSPECIFIED:                                                           //如果没有指定大小，就设置为默认大小
                result = defaultSize;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY:
                result = size;
                break;
        }
        return result;
    }

    /**
     * 开启自动增长
     */
    public void startIncrease() {
        isAutoIncrease = true;
        stopWave = false;
        invalidate();
    }

    /**
     * 设置当前进度,0-100之间
     * @param progress 进度
     */
    public void setProgress(int progress) {
        if (progress > 100 || progress < 0)
            throw new RuntimeException(getClass().getName() + "value between（0-100");

        stopWave = false;
        this.progress = progress;
        invalidate();
    }

    /**
     * 通过动画设置当前进度
     * @param targetProcess 进度 <=100
     * @param duration      动画时长
     */
    public void setProgress(final int targetProcess, int duration) {
        if (progress > 100 || progress < 0)
            throw new RuntimeException(getClass().getName() + "value between（0-100");

        ValueAnimator progressAnimator = ValueAnimator.ofInt(progress, targetProcess);
        progressAnimator.setDuration(duration);
        progressAnimator.setTarget(progress);
        progressAnimator.setInterpolator(new LinearInterpolator());
        progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                setProgress((Integer) animation.getAnimatedValue());
            }
        });
        progressAnimator.start();
    }

    /**
     * 获取当前进度
     * @return 当前进度
     */
    public int getProgress() {
        return progress;
    }
}
